/*
 * CSMSManager.cpp
 *
 *  Created on: Dec 21, 2011
 *      Author: ToanNhan
 */

#include "../inc/CSMSManager.h"
#include <smsuaddr.h>
#include <smsustrm.h>
#include <f32file.h>
#include <aknnotewrappers.h>
#include <gsmupdu.h>
#include <Gsmuelem.h>

CSMSManager::CSMSManager() : CActive(CActive::EPriorityStandard)
    {
        CActiveScheduler::Add(this);
    }

CSMSManager::~CSMSManager()
	{
        Cancel();
        iSocketServer.Close();
        iFs.Close();
        if (iSmsMessage)
            {
                delete iSmsMessage;
                iSmsMessage = NULL;
            }
        
        if (gpsRequest)
        	{
        	delete gpsRequest;
        	gpsRequest = NULL;
        	}
    }

CSMSManager* CSMSManager::NewL()
    {
        CSMSManager* smsManager = CSMSManager::NewLC();
        CleanupStack::Pop(smsManager);
        return smsManager;
    }

CSMSManager* CSMSManager::NewLC()
    {
        CSMSManager* smsManager = new (ELeave) CSMSManager();
        CleanupStack::PushL(smsManager);
        smsManager->ConstructL();
        return smsManager;
    }

void CSMSManager::ConstructL()
    {
        iRead = ETrue;
        iFs.Connect();
        iSocketServer.Connect();
        smsHandler = CSmsHandler::NewL();
        gpsRequest = CGpsPositionRequest::NewL(_L("Auto SMS"));
    }

void CSMSManager::SocketListener()
	{
	_LIT(KTag, "");
	TBuf8<2> matchTag;
	matchTag.Copy(KTag);

	//Opens a socket by creating a new subsession to the socket server.
	TInt err = iSocket.Open(iSocketServer, KSMSAddrFamily, KSockDatagram,
			KSMSDatagramProtocol);
	if (err == KErrNone)
		{
		//TRequestStatus iStatus;
		TSmsAddr smsaddr;
		// App. listens for sms msgs with some special tag in it.
		smsaddr.SetSmsAddrFamily(ESmsAddrMatchText);
		smsaddr.SetTextMatch(matchTag);
		TInt BindErr = iSocket.Bind(smsaddr);
		if (BindErr == KErrNone)
			{
			iPckgBuf() = KSockSelectRead;
			//Applies an asynchronous I/O control operation on a socket.
			iSocket.Ioctl(KIOctlSelect, iStatus, &iPckgBuf, KSOLSocket);
			iRead = ETrue;
			if (!IsActive())
				{
				SetActive();
				}
			}

		}
	}

void CSMSManager::RunL()
	{
	if (iRead)
		{
		CSmsBuffer *smsBuffer = CSmsBuffer::NewL();
		CleanupStack::PushL(smsBuffer);
		//Stream that reads a CSmsMessage object across a socket.
		RSmsSocketReadStream readStream(iSocket);
		//Allocates and creates a CSmsMessage
		//ESmsDeliver-SMS-DELIVER, sent from service center to Mobile Station. 
		iSmsMessage = CSmsMessage::NewL(iFs, CSmsPDU::ESmsDeliver, smsBuffer);
		//Internalises data from stream to CSmsMessage
		iSmsMessage->InternalizeL(readStream);
		readStream.Close();
		//Extracting the received message to a buffer	
		iSmsMessage->Buffer().Extract(iBuf, 0, iSmsMessage->Buffer().Length());
		iSocket.Ioctl(KIoctlReadMessageSucceeded, iStatus, &iPckgBuf,
				KSolSmsProv);
		CleanupStack::PopAndDestroy(smsBuffer);
		//Printing the received Message.
		if (iBuf.Compare(_L("were are you")) == 0)
			{
			TBuf<160> contentSend;
			TReal lon;
			TReal lat;
			TBool result = EFalse;
			TRAPD(err, gpsRequest->FetchCurrentPostionL(lat, lon, result));

			if (err == KErrNone && result)
				{
				contentSend.Format(
						_L("Hi, I am at here : http://maps.google.com/maps?q=%f,%f"),
						lat, lon);
				}
			else
				{
				if (err != KErrNone) 
					{
					contentSend.Format(_L("error code: %d"), err);
					}
				else
					{
					contentSend.Copy(_L("i do not know where i am"));
					}
				}

			TPtrC body(contentSend);
			TPtrC to(iSmsMessage->ToFromAddress());
			SendSMSL(to, body);
			}
		else
			{
			smsHandler->CreateLocalSMS(iSmsMessage->ToFromAddress(), iBuf);
			}
		//iRead = EFalse;
		//SocketListener();
		//iPckgBuf() = KSockSelectRead;
		//Applies an asynchronous I/O control operation on a socket.
		SetActive();
		}
	}

void CSMSManager::DoCancel()
    {
        iSocket.CancelIoctl();
    }

TBool CSMSManager::SendSMSL(TDesC& toNumber, TDesC& content)
    {
        /*TInt err1 = iSocket.Open(iSocketServer, KSMSAddrFamily, KSockDatagram,
                KSMSDatagramProtocol);
        if (!err1)
            {
                TSmsAddr smsaddr;
                smsaddr.SetSmsAddrFamily(ESmsAddrSendOnly);
                TInt BindErr1 = iSocket.Bind(smsaddr);
                if (BindErr1 == KErrNone)
                    {
                        CSmsBuffer *buffer = CSmsBuffer::NewL();
                        CleanupStack::PushL(buffer);
                        buffer->InsertL(0, content);
                        RSmsSocketWriteStream writestream(iSocket);
                        iSmsMessage = CSmsMessage::NewL(iFs, CSmsPDU::ESmsSubmit,
                                buffer);
                        TBuf<16> msgCenter;
                        GetMessageCenterL(msgCenter);
                        iSmsMessage->SmsPDU().SetServiceCenterAddressL(msgCenter);
                        iSmsMessage->SmsPDU().SetToFromAddressL(toNumber);
                        iSmsMessage->ExternalizeL(writestream);
                        writestream.CommitL();
                        TPckgBuf<TInt> sendBuffer;
                        sendBuffer = KSockSelectWrite;
                        iSocket.Ioctl(KIoctlSendSmsMessage, iStatus, &sendBuffer,
                                KSolSmsProv);
                        //iRead = EFalse;
                        //SetActive();
                        CleanupStack::PopAndDestroy(buffer);
                    }
            }*/
	RSendAs sendAs;
	TInt err = sendAs.Connect();
	if (err)
		{
		return false;
		}
	
	CleanupClosePushL(sendAs);
	
	RSendAsMessage sendAsMessage;
	sendAsMessage.CreateL(sendAs, KUidMsgTypeSMS);
	CleanupClosePushL(sendAsMessage);
	sendAsMessage.AddRecipientL(toNumber, RSendAsMessage::ESendAsRecipientTo);
	sendAsMessage.SetBodyTextL(content);
	
	sendAsMessage.SendMessageAndCloseL();
	CleanupStack::Pop();
	CleanupStack::PopAndDestroy();
	return true;
    }

void CSMSManager::GetMessageCenterL(TDes& aMsgCenter)
	{
	CMsvSession* pSession;
	pSession = CMsvSession::OpenSyncL(*this);

	CleanupStack::PushL(pSession); CClientMtmRegistry* pClientMtmReg = CClientMtmRegistry::NewL(*pSession);
	CleanupStack::PushL(pClientMtmReg);
	CSmsClientMtm* pSmsMtm = (CSmsClientMtm*)(pClientMtmReg->NewMtmL(KUidMsgTypeSMS));
	
	CSmsSettings& aSmsSettings = pSmsMtm->ServiceSettings();
	CSmsServiceCenter& aSmsServiceCenter = aSmsSettings.GetServiceCenter(aSmsSettings.DefaultServiceCenter());
	aMsgCenter.Copy(aSmsServiceCenter.Address());
	delete pSmsMtm;
	CleanupStack::PopAndDestroy(2);
	} 

void CSMSManager::HandleSessionEventL( TMsvSessionEvent aEvent, TAny* aArg1,
        TAny* aArg2, TAny* aArg3 )
	{
	
	}
